﻿using UnityEngine;
using System.Collections;
using YanhuaMMO;
using System;
using SimpleJSON;
using DG.Tweening;

public enum ShakeStyle
{
    RandomShake,
    SinShake
}
public enum ShakeType
{
    SphereType,//球形抖动
    Linear,//直线抖动
    RightDown,//右下倾斜
    LeftDown,//左下倾斜

}

public class CameraShake : MonoBehaviour
{

    public ShakeType shaketype;

    public ShakeStyle shakestyle;

    public bool isZoomEffect = false;

    private Transform zoomtarget;

    private float zoomtime = 1;

    private float shake = 0f;
    private float totalshaketime = 0;
    private Vector3 oldPos;

    // 抖动幅度（振幅）
    //振幅越大抖动越厉害
    private float shakeAmount = 0.05f;
  //  private float decreaseFactor = 1.0f;
    //镜头推近距离，越大推的越近
    private float movedist = 4;

    private bool reback = false;

    public float curStrength = 0f;

    public float shakeStrength = 1f;
    public float passtime = 0;


    //正弦震动

    public Vector3 positionShake;//震动幅度
    public Vector3 angleShake;   //震动角度
    public float cycleTime = 0.2f;//震动周期
    public bool fixShake = false; //为真时每次幅度相同，反之则递减
  //  public bool unscaleTime = false;//不考虑缩放时间
    public bool bothDir = true;//双向震动


    float currentTime;
    int curCycle;
    Vector3 curPositonShake;
    Vector3 curAngleShake;
    Vector3 startPosition;
    Vector3 startAngles;
    Transform myTransform;

    public SpriteRenderer blackbg;
    private void Awake()
    {
        //实际振幅
        shakeAmount = 0.04f;
        oldPos = transform.localPosition;
        InitMoveFoward();
    }
    private void Update()
    {
        return;
        if (shake > 0)
        {
            if (shakestyle == ShakeStyle.RandomShake)
            {
                UpdateShake();
            }
            else
                sinShake();

            shake -= Time.deltaTime;
            if (shake <= 0)
            {
                if(reback)
                    transform.localPosition = startPosition;
                else
                    transform.localPosition = oldPos;

                resetSinShake();
            }

            //  passtime += Time.deltaTime;
            return;
            // transform.localPosition = transform.localPosition + new Vector3(UnityEngine.Random.Range(-1 * horiMax, horiMax), UnityEngine.Random.Range(-1 * vertMax, vertMax), //UnityEngine.Random.Range(-1 * inoutMax, inoutMax));
            Vector3 randvector = UnityEngine.Random.insideUnitSphere;
            //randvector = new Vector3(randvector.x * shakeScale.x, randvector.y * shakeScale.y, randvector.z * shakeScale.z);
           // float shakemout = shakeAmount * (1 - (shake - totalshaketime / 2) * (shake - totalshaketime / 2) / UnityEngine.Mathf.Pow(totalshaketime / 2, 2));
            float shakemout = shakeAmount * (totalshaketime*0.5f - UnityEngine.Mathf.Abs(shake - totalshaketime*0.5f))/(totalshaketime * 0.5f);
           // Debug.Log("shakeamout:" + shakemout);
            transform.localPosition = transform.localPosition + randvector * shakemout; 

           //  shake -= Time.deltaTime * decreaseFactor;

            if (shake < 0 && !reback)
                transform.localPosition = oldPos;
        }
        else
        {
            shake = 0f;
            // transform.localPosition = transform;
        }

    }

    public void UpdateShake()
    {
        if (shake > 0.0f && totalshaketime > 0.0f)
        {
            float percent = shake / totalshaketime;
            if (shake > totalshaketime / 2)
                curStrength = Mathf.Lerp(curStrength, shakeStrength, 1 - percent);
            else
                curStrength = Mathf.Lerp(curStrength, 0, 0.5f);
            //Debug.Log("shanketime:" + shake + "," + shakeVector);
            Vector3 shakePos = Vector3.zero;

            shakePos.x = UnityEngine.Random.Range(-Mathf.Abs(curStrength) , Mathf.Abs(curStrength));
            shakePos.y = UnityEngine.Random.Range(-Mathf.Abs(curStrength) , Mathf.Abs(curStrength));
            shakePos.z = UnityEngine.Random.Range(-Mathf.Abs(curStrength) , Mathf.Abs(curStrength));

            if (shaketype == ShakeType.LeftDown)
            {
                 shakePos = new Vector3(shakePos.x, shakePos.x, 0);
            }
            else if (shaketype == ShakeType.RightDown)
            {
                shakePos = new Vector3(shakePos.x, -shakePos.x, 0);
            }
            else if(shaketype == ShakeType.Linear)
                shakePos = new Vector3(shakePos.x, shakePos.y*0.1f, 0);

            transform.position = startPosition + shakePos;

          
        }
        else
        {
            shake = 0.0f;
            totalshaketime = 0.0f;
        }
    }

    void sinShake()
    {

#if UNITY_EDITOR
       // if (fCycleCount > 0)
        //    cycleCount = Mathf.RoundToInt(fCycleCount);
#endif

        float deltaTime =  Time.deltaTime;
        currentTime += deltaTime;
        while (currentTime >= cycleTime)
        {
            currentTime -= cycleTime;
            curCycle++;
            //if (curCycle >= cycleCount)
            //{
            //    myTransform.localPosition = startPosition;
            //    myTransform.localEulerAngles = startAngles;
            //    return;
            //}

            if (!fixShake)
            {
                if (positionShake != Vector3.zero)
                    curPositonShake = (totalshaketime - shake) * positionShake / totalshaketime;
            }
        }

       // if (curCycle < cycleCount)
        {
            float offsetScale = Mathf.Sin((bothDir ? 2 : 1) * Mathf.PI * currentTime / cycleTime);
            if (positionShake != Vector3.zero)
                myTransform.localPosition = startPosition + curPositonShake * offsetScale;
            if (angleShake != Vector3.zero)
                myTransform.localEulerAngles = startAngles + curAngleShake * offsetScale;
        }
    }

    public void resetSinShake()
    {

        currentTime = 0f;
        curCycle = 0;
        curPositonShake = positionShake;
        curAngleShake = angleShake;
        myTransform = transform;
        startPosition = myTransform.localPosition;
        startAngles = myTransform.localEulerAngles;

    }

    IEnumerator InitMoveFoward()
    {
        object[] globalcfg = Util.CallMethod("OffLine", "loadData", "Global");

        while (globalcfg == null || globalcfg.Length <= 0)
        {
            yield return 0;
            globalcfg = Util.CallMethod("OffLine", "loadData", "Global");
        }

        String jsonStr = globalcfg[0] as String;

        JSONNode globalConfig = JSON.Parse(jsonStr);
        foreach (var item in globalConfig.Values)
        {
            if (item["ID"] == 109)
            {
                movedist = int.Parse(item["FunParameter"]);
            }
        }
    }


    public void StartShake(float shaketime, float delaytime,Vector3 offset,int shakeType,float shakeStr, float shakePower)
    {
        StartCoroutine(Delayshake(shaketime, delaytime, offset, shakeType, shakeStr,shakePower)); 
    }

    IEnumerator Delayshake(float shaketime, float delaytime, Vector3 offset, int shakeType, float shakeStr,float shakePower)
    {
        yield return new WaitForSeconds(delaytime / 1000);
        Tweener t = transform.DOShakePosition(shaketime / 1000, new Vector3(0,shakePower,0), (int)shakeStr, shakeType * 90);
        {
            if (reback == false)
                transform.position = oldPos;
        };
       
        //shake = shaketime / 1000;
        //shaketype = (ShakeType)shakeType;
        //shakeStrength = shakeStr;
        //totalshaketime = shake;
        //curStrength = 0;
        //resetSinShake();
        //transform.localPosition = transform.localPosition + offset;
        //transform.DOMove(oldPos, duration, false).SetEase(Ease.OutElastic);
        //Vector3 v = transform.localPosition.normalized;
    }

    public void OnDisable()
    {
        StopAllCoroutines();
        isZoomEffect = false;
    }

    public void EndZoom(float duration,float delayTime)
    {
        StartCoroutine(DelayEndZoom(delayTime, duration ));
    }

    IEnumerator DelayEndZoom(float delaytime, float duration)
    {
        yield return new WaitForSeconds(delaytime / 1000);
        Tweener t =  transform.DOMove(oldPos, duration, false).SetEase(Ease.OutSine);
        t.onComplete = () => { reback = false; startPosition = transform.position; };
       
    }

    public void ZoomMove(Vector3 newPos, float duration)
    {
       // transform.DOMove(newPos, duration, false).SetEase(Ease.InOutCirc);
    }

    public void StartZoomIn( float duration,Vector3 pos,float delayTime, float backtime,float zoomdist)
    {
        reback = true;
        StartCoroutine(DelayZoomIn(duration, pos, delayTime, backtime,zoomdist));
    }
    IEnumerator DelayZoomIn(float duration, Vector3 pos, float delaytime,float backtime,float zoomdist)
    {
        
        Vector3 tarPos = Vector3.Normalize(pos - oldPos) * zoomdist + oldPos;
        Tweener t = transform.DOMove(tarPos, duration/1000, false).SetEase(Ease.InSine);
        yield return new WaitForSeconds(delaytime / 1000);
        EndZoom(backtime / 1000, 0);
    }

    IEnumerator MoveToTarget(Vector3 pos, float duration)
    {
        float times = Time.deltaTime;
        //while (Vector3.Distance(transform.localPosition, oldPos) < 5)
        //{
        //    if (end)
        //        yield break;

        //    speed -= a * Time.deltaTime;
        //    transform.localPosition = Vector3.MoveTowards(transform.localPosition, pos, speed * Time.deltaTime);
        //   // Debug.Log(transform.localPosition);
        //    yield return 0;
        //}
        yield break;
    }

    public void StartScaleTime(float delaytime,float passtime,float targetScale,float pausetime,float resettime,float resevalue)
    {
        StartCoroutine(CoScaleTime(delaytime, passtime, targetScale, pausetime, resettime, resevalue));

    }

    IEnumerator CoScaleTime(float delaytime, float passtime, float targetScale, float pausetime, float resettime, float resevalue)
    {
        yield return new WaitForSeconds(delaytime / 1000);
        Tweener tt = DOTween.To(delegate (float value)
        {
            Time.timeScale = value;
        }, Time.timeScale, targetScale, passtime/1000).SetEase(Ease.InExpo);
        yield return new WaitForSeconds(pausetime / 1000);

        DOTween.To(delegate (float value)
        {
            Time.timeScale = value;
        }, Time.timeScale, resevalue, resettime/1000).SetEase(Ease.Linear);gameObject.GetComponent<MeshRenderer>().material.renderQueue = 3100;

    }
    public void showSpBg(int showorhide)
    {
        blackbg.gameObject.SetActive(showorhide == 1);
    }
    public void StartFadeBgImage(float delaytime,float fadetime,float targetalpha, float pausetime,float resettime)
    {
        StartCoroutine(fadeBackGroud(delaytime, fadetime,targetalpha, pausetime, resettime));
    }
    IEnumerator fadeBackGroud(float delaytime, float fadetime,float targetalpha,float pausetime, float resettime)
    {
        yield return new WaitForSeconds(delaytime/1000);

        if (blackbg)
        {
            blackbg.DOFade(targetalpha, fadetime/1000).SetEase(Ease.OutSine);
            yield return new WaitForSeconds(pausetime/1000);
            blackbg.DOFade(0, resettime/1000).SetEase(Ease.InSine);

        }

    }
}
